require 'logger'
require 'S3'
class S3Model

  # get Logger
  @logger = Logger.new(STDOUT)
  
  @config_file = File.join(RAILS_ROOT, 'config/s3_config.yml')
  
  # bucket_prefix: use this as the prefix for buckets;
  # will be set from bucket_prefix in aws_keys.yaml if defined; otherwise defaults to aws access key
  def initialize(config_file=@config_file, bucket_prefix=nil)
    config = File.open(config_file) { |f| YAML::load(f) }
    @aws_access_key = config['aws_access_key']
    @logger.error "key" + @aws_access_key
    @aws_secret_access_key = config['aws_secret_access_key']
    @logger.error "key" + @aws_secret_access_key
    @ssl = config['use_ssl'] || false
    if @ssl
      @logger.debug("SSL is enabled")
    else 
      @logger.debug("SSL is disabled")
    end
    @bucket_prefix = bucket_prefix || config['bucket_prefix'] || @aws_access_key
    @conn = S3::AWSAuthConnection.new(@aws_access_key, @aws_secret_access_key, @ssl)
  end
      
  # lists buckets
  def self.list_buckets
    @conn.list_all_my_buckets.entries
  end
  
  # lists contents of a bucket
  def self.list_bucket(bucket)
    @conn.list_bucket(bucket).entries
  end
  
  # creates a bucket
  def self.create_bucket(bucket)
    @conn.create_bucket(bucket).http_response.message
  end  
  
  # deletes a bucket
  def self.delete_bucket(bucket)
    @conn.delete_bucket(bucket).http_response.message
  end  
    
  # sets ACL to public-read
  def self.set_acl_public_read(bucket, key={})
    if key == {}
      acl_xml = @conn.get_bucket_acl(bucket).object.data
      @logger.debug('--- ACL before ---')
      @logger.debug(acl_xml)
      updated_acl = S3Helper.set_acl_public_read(acl_xml)
      @logger.debug('--- ACL after  ---')
      @logger.debug(updated_acl)
      @logger.debug('------------------')
      @conn.put_bucket_acl(bucket, updated_acl).http_response.message
    else 
      acl_xml = @conn.get_acl(bucket, key).object.data
      @logger.debug('--- ACL before ---')
      @logger.debug(acl_xml)
      updated_acl = S3Helper.set_acl_public_read(acl_xml)
      @logger.debug('--- ACL after  ---')
      @logger.debug(updated_acl)
      @logger.debug('------------------')
      @conn.put_acl(bucket, key, updated_acl).http_response.message
    end
  end

  # sets ACL to private
  def self.set_acl_private(bucket, key={})
    if key == {}
      acl_xml = @conn.get_bucket_acl(bucket).object.data
      @logger.debug('--- ACL before ---')
      @logger.debug(acl_xml)
      updated_acl = S3Helper.set_acl_private(acl_xml)
      @logger.debug('--- ACL after  ---')
      @logger.debug(updated_acl)
      @logger.debug('------------------')
      @conn.put_bucket_acl(bucket, updated_acl).http_response.message
    else 
      acl_xml = @conn.get_acl(bucket, key).object.data
      @logger.debug('--- ACL before ---')
      @logger.debug(acl_xml)
      updated_acl = S3Helper.set_acl_private(acl_xml)
      @logger.debug('--- ACL after  ---')
      @logger.debug(updated_acl)
      @logger.debug('------------------')
      @conn.put_acl(bucket, key, updated_acl).http_response.message
    end
  end

  # deletes a key
  def self.delete_key(bucket, key)
    @conn.delete(bucket, key).http_response.message
  end  
  
  # adds a key
  def self.put_file(bucket, key, data, headers)
    @conn.put(bucket, key, data, headers)
  end
  
  def self.generate_query_url(bucket,key)
    config = File.open(@config_file) { |f| YAML::load(f) }
    @aws_access_key = config['aws_access_key']
    @aws_secret_access_key = config['aws_secret_access_key']
    @ssl = config['use_ssl'] || false
    if @ssl
      @logger.debug("SSL is enabled")
    else 
      @logger.debug("SSL is disabled")
    end
    @generator = S3::QueryStringAuthGenerator.new(@aws_access_key, @aws_secret_access_key, @ssl)
    @generator.get(bucket,key)
  end
  
  # def self.test_url
  #   self.generate_query_url('zhangxue','snow_avatar_small.gif')
  # end
  # 
  # def self.put_and_set_acl_public
  #   file = File.new('/Users/zhangxue/Pictures/snow_avatar_10.jpg')
  #   @conn.put('zhangxue','snow_avatar_10.jpg',file.read,{'x-amz-acl'=>'public-read','Content-Type'=>'jpg'})
  # end
  def backup_to_s3(file_path)
    @bucket_name = 'ssss'
    @file_path = file_path 
    if File.exist?(@file_path)
      ## backup file
      file_to_upload = File.new(@file_path)
      @base_filename = file_to_upload.path.split('/').last
      file_data = file_to_upload.read
      content_type = 'flv'
      ## upload the file to s3, setting its acl to "public-read"
      S3Model.put_file(@bucket_name, @base_filename, file_data, 
      { 'Content-Type' => content_type,'x-amz-acl'=>"public-read" }
      )
      logger.debug "File #{@base_filename} has been backed-up to s3"
    else
      logger.debug "File doesn't exist"
    end
  end
  
  private
  def generate_s3_address
    "http://s3.amazonaws.com/#{VIDEO_CONVERTER_BUCKET}/#{@base_filename}"
  end
end
